package com.laiqilin.handler;

import com.laiqilin.excep.BusinessException;
import com.laiqilin.excep.NotPermissionException;
import com.laiqilin.utils.R;
import com.laiqilin.utils.ResponseEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.NoHandlerFoundException;

@RestControllerAdvice // 全局异常处理类
@Slf4j // 使用@Slf4j来记录日志
public class HzitGlobalExceptionHandler {

	/**
	 * 处理没有权限的异常
	 */
	@ExceptionHandler(NotPermissionException.class)
	public R handlerNotPermissionException(NotPermissionException e){
		log.error("出现了异常：{}", e.getMessage()); // 打印错误日志
		return R.error().message(e.getMessage()); // 返回错误响应
	}

	/**
	 * 处理所有异常
	 */
	@ExceptionHandler(Exception.class)
	public R handleException(Exception e){
		log.error(e.getMessage(), e); // 打印错误日志
		return R.error(); // 返回通用错误响应
	}

	/**
	 * 处理SQL语法错误的异常
	 */
	@ExceptionHandler(BadSqlGrammarException.class)
	public R handleBadSqlGrammarException(BadSqlGrammarException e){
		log.error(e.getMessage(), e); // 打印错误日志
		return R.setResult(ResponseEnum.BAD_SQL_GRAMMAR_ERROR); // 返回SQL语法错误响应
	}

	/**
	 * 处理SQL约束违反的异常
	 */
	@ExceptionHandler(DataIntegrityViolationException.class)
	public R handleSqlException(DataIntegrityViolationException e){
		log.error("异常信息：{}", e.getMessage()); // 打印错误日志
		return R.setResult(ResponseEnum.BAD_SQL_AMBIGUOUS); // 返回SQL约束违反响应
	}

	/**
	 * 处理自定义的业务异常
	 */
	@ExceptionHandler(BusinessException.class)
	public R handleBusinessException(BusinessException e){
		log.error(e.getMessage(), e); // 打印错误日志
		return R.error().message(e.getMessage()).code(e.getCode()); // 返回带有错误码和信息的响应
	}

	/**
	 * 处理其他Servlet相关的异常
	 */
	@ExceptionHandler({
			NoHandlerFoundException.class,
			HttpRequestMethodNotSupportedException.class,
			HttpMediaTypeNotSupportedException.class,
			MissingPathVariableException.class,
			MissingServletRequestParameterException.class,
			TypeMismatchException.class,
			HttpMessageNotReadableException.class,
			HttpMessageNotWritableException.class,
			MethodArgumentNotValidException.class,
			HttpMediaTypeNotAcceptableException.class,
			ServletRequestBindingException.class,
			ConversionNotSupportedException.class,
			MissingServletRequestPartException.class,
			AsyncRequestTimeoutException.class
	})
	public R handleServletException(Exception e) {
		log.error(e.getMessage(), e); // 打印错误日志
		return R.error().message(ResponseEnum.SERVLET_ERROR.getMessage()).code(ResponseEnum.SERVLET_ERROR.getCode()); // 返回Servlet相关错误响应
	}
}
